﻿using SuperMap.Data;
using SuperMap.Realspace;
using SuperMap.Realspace.SpatialAnalyst;
using SuperMap.UI;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Ycjw.PipeLine.Map.Basic.SuperMap;

namespace Ycjw.PipeLine.Map.Tools.Conditions.ProfileAnalyst
{
    public class SceneProfileAnalyst : SceneOperInterface
    {

        public override void UnRegister()
        {
            m_SceneControl.MouseDown -= new MouseEventHandler(SceneControl_MouseDown);
            m_SceneControl.MouseMove -= new MouseEventHandler(SceneControl_MouseMove);
            if(!m_SceneControl.IsDisposed)
                this.m_SceneControl.Scene.TrackingLayer.Clear();

            base.UnRegister();
        }

        private Datasource m_datasource;
        private DatasetGrid m_Surface;
        private DatasetVector[] m_Models;

        private Boolean m_CanDrawLine;
        private Point2D m_StartPoint;
        private Point2D m_EndPoint;
        private Int32 m_Count;

        ProfileAnalystForm m_FormResult;

        /// <summary>
        /// 初始化控件和数据
        /// Initialize the control and data
        /// </summary>
        public SceneProfileAnalyst(SceneControl sceneControl,Form formMain) : base(sceneControl, formMain)
        {
            m_SceneControl = sceneControl;

        }

        DatasetGrid GetDatasetGrid()
        {
            DatasetGrid result = null;
            foreach (TerrainLayer lyr in m_SceneControl.Scene.TerrainLayers)
            {
                if (lyr.Dataset is DatasetGrid)
                {
                    result = lyr.Dataset as DatasetGrid;
                    break;
                }
            }
            return result;
        }

        List<DatasetVector> GetDatasetVectors()
        {
            var result = new List<DatasetVector>();
            foreach (Layer3D lyr in m_SceneControl.Scene.Layers)
            {
                if (lyr.Type == Layer3DType.Dataset)
                {
                    if (!(lyr is Layer3DDataset)) continue;
                    var dataset = (lyr as Layer3DDataset).Dataset;

                    if (dataset.Type != DatasetType.Line 
                        && dataset.Type != DatasetType.Line3D
                        && dataset.Type != DatasetType.Network
                        && dataset.Type != DatasetType.Network3D) continue;

                    result.Add(dataset as DatasetVector);
                }
            }
            return result;
        }

        /// <summary>
        /// 打开工作空间，并加载数据到场景；注册事件
        /// Open the workspace and add the data to the scene. Register the event
        /// </summary>
        private void Initialize()
        {
            try
            {
                // 注册事件
                // Add event
                m_SceneControl.MouseDown -= new MouseEventHandler(SceneControl_MouseDown);
                m_SceneControl.MouseMove -= new MouseEventHandler(SceneControl_MouseMove);

                m_SceneControl.MouseDown += new MouseEventHandler(SceneControl_MouseDown);
                m_SceneControl.MouseMove += new MouseEventHandler(SceneControl_MouseMove);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public void GetCamera()
        {
            Camera c = m_SceneControl.Scene.Camera;
            Console.WriteLine(c.ToString());
        }

        /// <summary>
        /// 开始绘制
        /// Start drawing
        /// </summary>
        public void StartDraw()
        {
            try
            {
                Initialize();
                m_Count = 0;
                m_StartPoint = new Point2D();
                m_EndPoint = new Point2D();
                m_SceneControl.Scene.TrackingLayer.Clear();
                m_SceneControl.Scene.Refresh();
                m_CanDrawLine = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 鼠标按下时，选取切割线的起点和终点
        ///  Mouse listener event
        /// </summary>
        private void SceneControl_MouseDown(object sender, MouseEventArgs e)
        {
            try
            {
                // 单击左键
                // Click
                if (e.Button == MouseButtons.Left && m_CanDrawLine)
                {
                    m_Count++;
                    Point point = new Point(e.X, e.Y);
                    Point3D globePoint = m_SceneControl.Scene.PixelToGlobe(point, PixelToGlobeMode.Terrain);

                    if (globePoint != null)
                    {
                        if (m_Count % 2 == 1)
                        {
                            m_StartPoint.X = globePoint.X;
                            m_StartPoint.Y = globePoint.Y;
                        }
                        else
                        {
                            m_EndPoint.X = globePoint.X;
                            m_EndPoint.Y = globePoint.Y;
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 鼠标移动时，绘制切割线
        /// Draw the split line
        /// </summary>
        private void SceneControl_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                if (m_CanDrawLine)
                {
                    m_SceneControl.Cursor = Cursors.Cross;
                    if (m_StartPoint != null && m_Count > 0 && m_Count % 2 == 1)
                    {
                        Point point = new Point(e.X, e.Y);
                        Point3D currentPoint = m_SceneControl.Scene.PixelToGlobe(point);
                        Point3D fromPoint = new Point3D(m_StartPoint.X, m_StartPoint.Y, 0);
                        DrawLine(fromPoint, currentPoint);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 进行剖面分析，生成结果剖面线，并绘制二维剖面图
        /// Perform profile analysis and build result showed in graph
        /// </summary>
        public void Analyst()
        {
            try
            {
                if (m_StartPoint != null && m_EndPoint != null && m_StartPoint != m_EndPoint)
                {
                    m_CanDrawLine = false;
                    m_Surface = GetDatasetGrid();
                    m_Models = GetDatasetVectors().ToArray();
                    if (m_Models.Length > 0 || m_Surface != null)
                    {
                        m_datasource = m_Models[0].Datasource;
                        String resultName = "ProfileResult3D";
                        if (m_datasource.Datasets.Contains(resultName))
                        {
                            m_datasource.Datasets.Delete(resultName);
                        }
                        DatasetVector resultDatset = SuperMap.Realspace.SpatialAnalyst.ProfileAnalyst.CalculatePlumbProfile(m_StartPoint, m_EndPoint, m_Models, m_Surface, m_datasource, resultName, AltitudeMode.Absolute);
                        if (resultDatset != null)
                        {
                            if (m_FormResult != null)
                            {
                                if (m_FormResult.IsDisposed)
                                {
                                    m_FormResult = new ProfileAnalystForm(this.m_SceneControl.Scene.Workspace, 
                                        resultDatset, m_StartPoint, m_EndPoint, m_datasource);
                                    m_FormResult.Show();
                                }
                                else
                                {
                                    m_FormResult.Refresh(resultDatset, m_StartPoint, m_EndPoint);
                                }
                            }
                            else
                            {
                                m_FormResult = new ProfileAnalystForm(this.m_SceneControl.Scene.Workspace, resultDatset, m_StartPoint, m_EndPoint, m_datasource);
                                m_FormResult.Show();
                            }

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 在跟踪层上绘制切割线
        /// Add line in tracking layer
        /// </summary>
        public void DrawLine(Point3D fromPoint, Point3D toPoint)
        {
            try
            {
                Point3Ds points = new Point3Ds
                {
                    fromPoint,
                    toPoint
                };
                GeoLine3D line = new GeoLine3D();
                line.AddPart(points);
                GeoStyle3D style = new GeoStyle3D
                {
                    LineColor = Color.Black,
                    LineWidth = 3
                };
                line.Style3D = style;
                m_SceneControl.Scene.TrackingLayer.Clear();
                m_SceneControl.Scene.TrackingLayer.Add(line, "line");
                m_SceneControl.Scene.Refresh();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}
